<template>
  <div class="tableList flex-column g-box g-inside" :class="{ 'eleFull': isEleFull }">
    <div class="flex-hd">
      <div class="mb10">
        <slot name="formList"></slot>
      </div>
      <div class="toolbarList mb10" :multiples="options.multiples">
        <div class="left">
          <slot name="toolbarLeft">
            <slot name="toolbarLeftStart"></slot>
            <el-button type="primary" size="mini" icon="el-icon-plus" v-if="options.add"
                v-hasPermi="options.add.auth" @click="options.add.click">{{options.add.name || '新增' }}</el-button>
            <el-button type="info" size="mini" icon="el-icon-upload2" v-if="options.import"
              v-hasPermi="options.import.auth" @click="options.import.click">{{options.import.name || '导入' }}</el-button>
            <el-button type="warning" size="mini" icon="el-icon-download" v-if="options.export"
              v-hasPermi="options.export.auth" @click="options.export.click">{{options.export.name || '导出' }}</el-button>
            <el-button type="danger" size="mini" icon="el-icon-delete" v-if="options.del"
              v-hasPermi="options.del.auth" :disabled="options.multiples.length === 0"
              @click="options.del.click">{{options.del.name || '批量删除' }}</el-button>
            <slot name="toolbarLeftEnd"></slot>
          </slot>
        </div>
        <div class="right">
          <slot name="toolbarRight">
              <slot name="toolbarRightStart"></slot>
              <el-popover
                placement="bottom-end"
                width="220"
                trigger="click"
                popper-class="popper-columns"
                v-model="visible"
                v-show="options.showColumns === false ? false : true"
                @hide="getPage()">
                <div class="columns-list">
                  <div class="list-hd">表头设置</div>
                  <div class="list-bd" ref="columnsList">
                    <div class="item" v-for="item in currentColumns" :key="item.field" v-show="item.isFilter">
                      <div class="item-left">
                        <i class="el-icon-rank" style="margin-right: 10px;"></i>
                        <label :title="item.title"><el-checkbox v-model="item.visible">{{ item.title && item.title.length > 8 ? item.title.slice(0,6) + '...' : item.title}}</el-checkbox></label>
                      </div>
                      <div class="item-right">
                        <i title="固定在左侧" :class="[item.fixed === 'left' ? 'is--checked vxe-icon-fixed-left-fill' : 'vxe-icon-fixed-left']" @click="onFixedField(item, 'left')"></i>
                        <i title="固定在右侧" :class="[item.fixed === 'right' ? 'is--checked vxe-icon-fixed-right-fill' : 'vxe-icon-fixed-right']" @click="onFixedField(item, 'right')"></i>
                      </div>
                    </div>
                  </div>
                  <div class="list-ft">
                    <el-link :underline="false" @click="onResetColumns">重置</el-link>
                    <el-link :underline="false" @click="onSubmitColumns">确认</el-link>
                  </div>
                </div>
                <template slot="reference">
                  <el-tooltip effect="dark" content="筛选列" placement="top">
                    <el-button size="mini" circle icon="el-icon-s-grid" />
                  </el-tooltip>
                </template>
              </el-popover>
              <ScreenFull :isEleFull.sync="isEleFull" />
              <el-tooltip v-if="options.serch" effect="dark" :content="options.serch.show ? '隐藏搜索' : '显示搜索'" placement="top">
                <el-button size="mini" circle icon="el-icon-search" @click="options.serch.click" />
              </el-tooltip>
              <slot name="toolbarRightEnd"></slot>
          </slot>
        </div>
      </div>
    </div>
    <div class="flex-bd" style="overflow: hidden;">
      <vxe-grid 
        ref="table" 
        v-loading="options.loading" 
        v-bind="options.config" 
        v-on="options.method"
        @resizable-change="onResizableChange"
      >
        <template v-for="(index, name) in $scopedSlots" v-slot:[name]="data">
          <slot :name="name" v-bind="data"></slot>
        </template>
      </vxe-grid>
    </div>
    <el-pagination 
      class="mt10 flex-ft"
      v-if="options.pageMethod"
      :background="true"
      :align="options.pageConfig.align || 'right'"
      :pageSizes="options.pageConfig.pageSizes || [10, 20, 50, 100, 200, 500, 1000]"
      :layout="options.pageConfig.layout || 'total, sizes, prev, pager, next, jumper'"
      :page-size="$parent.tableParams.pageSize" 
      :current-page="$parent.tableParams.pageNum"
      v-bind="options.pageConfig"
      v-on="options.pageMethod"
    />
  </div>
</template>

<script>
import { deepCopy } from "@/utils/ruoyi"
import cache from '@/plugins/cache'
import ScreenFull from '@/components/Common/ScreenFull'
import Sortable from 'sortablejs'
export default {
  name: "TableList",
  components: {
    ScreenFull
  },
  props: ['options'],
  data() {
    return {
      isEleFull: false,
      visible: false,
      fullColumns: [],
      currentColumns: [],
      copyFullColumns: [],
      cachedPage: {
        all: [],
        current: null
      }
    };
  },
  computed: {
  },
  watch: {
    'options.config.data': {
      deep: true,
      handler() {
        this.init()
        this.getPage()
      }
    }
  },
  created() {
    // this.init()
    // this.getPage()
  },
  methods: {
    init(val){
      this.fullColumns =  this.options.config.columns //this.$refs['table']?.getTableColumn().fullColumn
      this.copyFullColumns = deepCopy(this.fullColumns)
      // 拖动
      this.$nextTick(() => {
        new Sortable(this.$refs['columnsList'], {
          animation: 150,
          ghostClass: 'blue-background-class',
          handle: ".el-icon-rank",
          onEnd: (evt) => {
            this.currentColumns.splice(evt.newIndex, 0, this.currentColumns.splice(evt.oldIndex, 1)[0]) 
          }
        })
      })
    },
    // 获取缓存的列数据
    getCached(){
      this.cachedPage.all = cache.local.getJSON('pageConfig') || []
      this.cachedPage.current = this.cachedPage.all.find(v => v.name === this.$parent.$options.name)
    },
    // 对比缓存，获取到最新的列数据
    getPage(){
      this.getCached()
      if(this.cachedPage.current){
        this.currentColumns = this.getNewColumns(deepCopy(this.copyFullColumns), this.cachedPage.current.columns)
      } else {
        this.currentColumns = this.getNewColumns(deepCopy(this.copyFullColumns), deepCopy(this.copyFullColumns))
      }
      this.getRefreshColumn()
    },
    // 获取最新的列数据
    getNewColumns(target, update){
      // 创建一个id到对象的映射，用于快速查找
      const idToObjectMap = new Map(target.map(obj => [obj.field, obj]));

      // 先处理缓存中的对象
      const newArray = update.map(obj => {
        // 如果缓存中的对象id在idToObjectMap中存在，返回该对象
        // 不存在过滤
        target.forEach(v => {
          if(obj.field === v.field){
            this.$set(v, 'fixed', obj.fixed)
            this.$set(v, 'visible', obj.visible)
            this.$set(v, 'width', obj.width)
          }
        })
        return idToObjectMap.get(obj.field) || {};
      }).filter(v => v.field)

      // 遍历默认列，找出那些还未在新数组中出现的对象
      // 根据默认列顺序插入
      target.forEach((obj,index) => {
        if (!newArray.some(newObj => newObj.field === obj.field)) {
          newArray.splice(index, 0, obj)
        }
      })
      return newArray
    },
    // 更新列
    getRefreshColumn(){
      this.$nextTick(() => {
        setTimeout(() => {
          this.$refs['table']?.reloadColumn(this.currentColumns)
        })
      })
    },
    // 设置列固定
    onFixedField(item, type){
      item.fixed = item.fixed === type ? null : type
    },
    // 重置列
    onResetColumns(){
      this.getCached()
      if(this.cachedPage.current){
        // 过滤缓存的列配置
        this.cachedPage.all = this.cachedPage.all.filter(v => v.name != this.$parent.$options.name)
        // 统一更新到local
        cache.local.setJSON('pageConfig', this.cachedPage.all)
      }
      // 关闭下拉，会自动更新列
      this.visible = false
      this.currentColumns = deepCopy(this.copyFullColumns)
      this.getRefreshColumn()
    },
    onSubmitColumns(){
      let columnsNew = this.currentColumns.filter(v => v.isFilter).map(v => {
        return {
          field: v.field,
          fixed: v.fixed,
          visible: v.visible,
          width: v.width
        }
      })
      this.getCached()
      // 存在缓存更新替换
      if(this.cachedPage.current){
        this.cachedPage.all.forEach(v => {
          if(v.name === this.$parent.$options.name){
            v.columns = columnsNew
          }
        })
      }else{// 不存在push
        this.cachedPage.all.push({
          name: this.$parent.$options.name,
          columns: columnsNew
        })
      }
      // 统一更新到local
      cache.local.setJSON('pageConfig', this.cachedPage.all)
      this.visible = false
      this.getRefreshColumn()
    },
    onResizableChange({column}){
      let current = this.currentColumns.find(v => v.field === column.field)
      if(current){
        current.width = column.renderWidth
        this.onSubmitColumns()
      }
    }
  }
};
</script>

<style scoped lang="scss">
::v-deep{
  .vxe-table .vxe-cell--sort{
    margin-top: -4px;
  }
  .vxe-table .c--tooltip{
    width: auto !important;
  }

  .vxe-table{
    .el-input,
    .el-textarea,
    .el-select,
    .el-date-editor{
      width: 100%;
    }
  }
}
</style>